package com.example.ccj.b.c.custom.tree;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SearchView;

import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.example.ccj.R;
import com.example.ccj.b.c.recycler.BaseRecycler;
import com.example.ccj.u.LogUtils;
import com.example.ccj.u.StringUtils;
import com.example.ccj.u.ToastUtils;
import com.example.ccj.u.server.MyObserver;
import com.example.ccj.u.sqlite.SqliteExcuteCommand;
import com.example.ccj.u.sqlite.TableBean;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;


/**
 * 树结构view
 * setData 设置数据   必须传的
 * setTitleName 设置目录名称
 * setShowLevel 设置默认显示级别
 * setOnlyShowMuLu 设置首次加载是否只显示目录
 * setSuoJinJiBie 子节点相对缩进级别,每个级别增加10dp
 * setMuLuDefaultImageResource 目录默认图片资源ID
 * setDataDefaultImageResource 数据默认图片资源ID
 * 最后调用show()
 *
 * @author 驰珺
 * whechat   : chijun9
 * create at : 2024/11/21 18:46
 */
public class TreeView extends LinearLayout implements ISelectTreeListener{

    private static final String sqlTableName = "tree_old_data";
    private List<TreeMode> showTreeModeList;                //显示的数据
    private List<TreeMode> searchTreeModeList;              //检索的数据
    private List<TreeMode> inPutTreeModeList;               //添加的数据
    private Map<Integer,TreeMode> selectTreeModeMap;        //已选择的数据
    private String titleName = "总目录";                     //总目录名称
    private int showLevel = 2;                              //开始加载显示的最大级别
    private boolean isOnlyShowMuLu = false;                 //最开始加载是否只显示目录
    private int iconMuLu = 0;                               //目录默认图片资源ID
    private int iconData = 0;                               //数据默认图片资源ID
    private int suoJinLevel = 3;                            //子节点相对缩进级别,每个级别增加10dp
    private ISelectTreeListener selectTreeListener;
    private SearchView searchView;
    private BaseRecycler<TreeMode> searchRecycler;
    private BaseRecycler<TreeMode> treeModeBaseRecycler;
    private ListView searchOldDataListView;
    TreeOldSearchDataAdapter adapter;


    public TreeView(Context context) {
        super(context);
    }

    public TreeView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    //设置总目录名称
    public TreeView setTitleName(String name){
        this.titleName = name;
        return this ;
    }
    //设置数据
    public TreeView setData(List<TreeMode> modeList){
        if (inPutTreeModeList != null) {

            LogUtils.d("数据数量：" + inPutTreeModeList.size() );
//            inPutTreeModeList .clear();
        }
        this.inPutTreeModeList = modeList;

        return this ;
    }
    //设置默认显示的数据级别
    public TreeView setShowLevel(int level){
        this.showLevel = level;
        return this ;
    }
    //设置首次加载只显示目录
    public TreeView setOnlyShowMuLu(boolean isOnlyShowMuLu){
        this.isOnlyShowMuLu = isOnlyShowMuLu;
        return this ;
    }
    //设置目录默认图片资源id
    public TreeView setMuLuDefaultImageResource(int imageResourceId){
        this.iconMuLu = imageResourceId;
        return this ;
    }
    //设置数据默认图片资源id
    public TreeView setDataDefaultImageResource(int imageResourceId){
        this.iconData = imageResourceId;
        return this ;
    }
    //设置缩进级别
    public TreeView setSuoJinJiBie(int suoJinLevel){
        this.suoJinLevel = suoJinLevel;
        return this ;
    }
    //设置选中取消选中回调
    public TreeView setSelectTreeListener(ISelectTreeListener selectTreeListener){
        this.selectTreeListener = selectTreeListener;
        return this ;
    }

    public void show(){
        init();
    }
    TreeMode zongMuLu;
    private void init(){
        LinearLayout.inflate(getContext(), R.layout.view_tree,this);
        createSqlTable();//创建历史数据表

        searchTreeModeList = new ArrayList<>();
        showTreeModeList = new ArrayList<>();
        selectTreeModeMap = new HashMap<>();
        treeModeBaseRecycler = findViewById(R.id.view_tree_rec);
        searchView = findViewById(R.id.view_tree_search);
        searchRecycler = findViewById(R.id.view_tree_search_rec);
        searchOldDataListView = findViewById(R.id.view_tree_search_list);

        if (inPutTreeModeList == null || inPutTreeModeList.isEmpty()) {
            ToastUtils.showShort("传入数据为空，请先传入数据");
            return;
        }

        zongMuLu = new TreeMode("0",null,titleName,TreeMode.DATA_TYPE_MU_LU,0);
        zongMuLu.treeModeList = new ArrayList<>();
        zongMuLu.id = 0;
        zongMuLu.pId = 0;
        zongMuLu.level = 0;
        zongMuLu.isExpand = true;
        zongMuLu.isVisibility = true;
        i = 0;
        LogUtils.d("处理之前遍历前I的值：" + i);
        binaliJiShu(zongMuLu);
        LogUtils.d("处理之前遍历计数的数量：" + i);

        for (TreeMode treeMode : inPutTreeModeList) {
            //没有上级的直接丢入总目录
            if (StringUtils.isEmpty(treeMode.pMuLu)) {
//                LogUtils.d("没有上级丢入总目录：" + treeMode);
                zongMuLu.treeModeList.add(treeMode);
                continue;
            }

            //有上级的遍历是否能找到他的上级，找到了由递归处理这里不管，没找到新建上级目录
            if (!diGui(zongMuLu,treeMode)) {
//                LogUtils.d("没找到他的上级新建他的上级目录：" + treeMode);
                TreeMode mulu = new TreeMode(treeMode.pMuLu,null,"临时",TreeMode.DATA_TYPE_MU_LU,0);
                mulu.treeModeList = new ArrayList<>();
                mulu.treeModeList.add(treeMode);
                zongMuLu.treeModeList.add(mulu);
            }
        }

        binaliJiShu(zongMuLu);
        LogUtils.d("遍历计数的数量：" + i);

        LogUtils.d("处理前数据数量：" + inPutTreeModeList.size());
        LogUtils.d("处理前数据数量：" + showTreeModeList.size());
        //排序
        sort(zongMuLu);
        LogUtils.d("处理后数据数量：" + showTreeModeList.size());
        //遍历
        bianLi(zongMuLu);
        //打印
//        LogUtils.d(stringBuilder);
        LogUtils.d("处理后数据数量：" + showTreeModeList.size());
        //初始显示所有数据
        allDataShow();
        //检索后数据显示的Recycler赋予初始值
        searchRecycler.setLayoutManager(new LinearLayoutManager(getContext()));
        searchRecycler.setAdapter(searchTreeModeList,new TreeSearchAdapter(searchTreeModeList,null,this));
        //初始化搜索
        initSearch();
    }

    private void allDataShow(){
        //数据放入展示  将其替换为普通Recycler即可
        TreeAdapter treeAdapter = new TreeAdapter(this.showTreeModeList, null, this);
        treeAdapter.setSuoJinJiBie(suoJinLevel);
        treeAdapter.setDataDefaultImageResource(iconData);
        treeAdapter.setMuLuDefaultImageResource(iconMuLu);
        treeModeBaseRecycler.setAdapter(this.showTreeModeList,treeAdapter);
    }

    private void initSearch(){

//        searchView.setIconified(false);//显示搜索框
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                // 当用户提交搜索关键字时触发
                searchOldDataListView.setVisibility(GONE);
                Map<String,String> map = new HashMap<>();
                map.put("name",query);
                SqliteExcuteCommand.save(getContext(),sqlTableName,map);
                search(searchView.getQuery());//查询
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                // 当搜索关键字发生变化时触发
                searchOldList(findOldSearchData(searchView.getQuery().toString()));
                search(searchView.getQuery());
                return true;
            }
        });

        searchView.setOnSearchClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 当搜索图标被点击时触发
                // 在这里执行操作，例如展示搜索历史记录等
                // 显示隐藏搜索框
                if (!searchView.isIconified()) {
                    searchOldList(findOldSearchData(null));
                }
            }
        });

        //搜索界面关闭
        searchView.setOnCloseListener(new SearchView.OnCloseListener() {
            @Override
            public boolean onClose() {
                searchOldDataListView.setVisibility(GONE);
                return false;
            }
        });
    }


    /**
     * 检索
     * @param newText 检索文本
     */
    private void search(CharSequence newText){
        if (StringUtils.isEmpty(newText)) {
            searchRecycler.setVisibility(GONE);
            treeModeBaseRecycler.setVisibility(View.VISIBLE);
            return;
        } else {
            searchRecycler.setVisibility(VISIBLE);
            treeModeBaseRecycler.setVisibility(View.GONE);
        }

        searchRecycler.removeAllData();
        Observable.create(new ObservableOnSubscribe<TreeMode>() {
            @Override
            public void subscribe(ObservableEmitter<TreeMode> e) throws Exception {
                for (TreeMode treeMode : showTreeModeList) {
                    if (treeMode.type == TreeMode.DATA_TYPE_DATA && treeMode.name.contains(newText)) {
                        treeMode.isVisibility = true;
                        e.onNext(treeMode);
                    }
                }
            }
        }).observeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new MyObserver<TreeMode>() {
            @Override
            public void onNext(TreeMode treeMode) {
                searchRecycler.addDataOnTail(treeMode);
//                treeModeBaseRecycler.getAdapter().notifyItemChanged(treeMode.id);
            }
        });
    }

    /**
     * 检索数据库历史搜索记录
     * @param val 检索字符
     */
    private List<String> findOldSearchData(String val){
        List<String> findData = new ArrayList<>();

        String findText = " name LIKE '%" + val +"%' " ;
        if (StringUtils.isEmpty(val)) findText = null;

        ArrayList<HashMap<String, String>> hashMaps =
                SqliteExcuteCommand.get(getContext(), sqlTableName, new String[]{"name"},findText, " id  DESC ", "5");
        for (HashMap<String, String> hashMap : hashMaps) {
            String s = hashMap.get("name");
            if (!StringUtils.isEmpty(s)) findData.add(s);
        }
        LogUtils.d( "查询条件：" + findText + "-查询到的数据：" + findData.size());
        return findData;
    }

    private void createSqlTable(){
        TableBean tableBean = new TableBean();
        tableBean.isKey = false;
        tableBean.name = "name";
        tableBean.type = TableBean.CHAR;

        TableBean tableBean1 = new TableBean();
        tableBean1.isKey = true;
        tableBean1.name = "id";
        tableBean1.type = TableBean.INT;

        List<TableBean> tableBeans = new ArrayList<>();
        tableBeans.add(tableBean);
        tableBeans.add(tableBean1);

        SqliteExcuteCommand.createTable(getContext(),sqlTableName,tableBeans);
    }

    /**
     * 显示搜索历史记录
     * @param list 历史记录
     */
    private void searchOldList(List<String> list){
        if (list == null || list.isEmpty()) {
            searchOldDataListView.setVisibility(GONE);
            return;
        }
        searchOldDataListView.setVisibility(View.VISIBLE);
        adapter = new TreeOldSearchDataAdapter(getContext(), R.layout.adapter_list_view_tree_old_search, list, new ISelectOldSearchTextListener() {
            @Override
            public void result(String val) {
                searchView.setQuery(val,true);
                searchOldDataListView.setVisibility(GONE);
            }
        });
        searchOldDataListView.setAdapter(adapter);

//        PopupMenu popupMenu = new PopupMenu(getContext(),view);
//        for (int i = 0; i < list.size(); i++) {
//            popupMenu.getMenu().add(Menu.NONE,i,i,list.get(i));
//        }
//
//        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
//            @Override
//            public boolean onMenuItemClick(MenuItem item) {
//                CharSequence title = item.getTitle();
//                search(title);
//                return false;
//            }
//        });
//        popupMenu.show();
    }


    StringBuilder stringBuilder = new StringBuilder();
    int id = 1;//数据编号

    /**
     * 递归根据order排序 并设置其显示级别以及id和上级目录id
     * 这个很重要，显示时要使用id以及目录id作为显示、不显、选中、不选中等依据
     * @param treeMode 要排序的
     */
    public void sort(TreeMode treeMode){
        if (treeMode != null) {
            List<TreeMode> treeModeList = treeMode.treeModeList;
            if (treeModeList != null) {
                Collections.sort(treeModeList);
                for (TreeMode mode : treeModeList) {
                    //数据的纵深级别
                    mode.level = treeMode.level + 1;
                    //数据加载序号
                    mode.id = id++;
                    //数据上级id
                    mode.pId = treeMode.id;
                    sort(mode);
                }
            }
        }
    }

    int i = 0;
    private void binaliJiShu(TreeMode treeMode){
        i++;
        if (treeMode.treeModeList != null) {
            for (TreeMode mode : treeMode.treeModeList) {
                binaliJiShu(mode);
            }
        }
    }



    /**
     * 遍历排序后的数据 将数据放入展示并且设置显示级别
     * @param treeMode 1
     */
    public void bianLi(TreeMode treeMode){
        if (treeMode != null) {
            //将数据放入
            showTreeModeList.add(treeMode);
            if (treeMode.isChecked) selectTreeModeMap.put(treeMode.id,treeMode);
            //根据显示级别设置是否显示
            if (treeMode.level < showLevel) {
                if (isOnlyShowMuLu && treeMode.type == TreeMode.DATA_TYPE_MU_LU) treeMode.isVisibility = true;
                else treeMode.isVisibility = true;
            }
            stringBuilder.append(treeMode).append("\n");
            List<TreeMode> treeModeList = treeMode.treeModeList;
            if (treeModeList != null) {
                for (TreeMode mode : treeModeList) {
                    stringBuilder.append(treeMode.dataId).append("--");
                    bianLi(mode);
                }
            }
        }
    }

    /**
     * 递归放入数据
     * @param treeMode 总目录
     * @param treeModeC 要查找的数据
     * @return  112
     */
    private boolean diGui(TreeMode treeMode,TreeMode treeModeC){
        //目录id一致将数据进行替换
        //查找数据本身一致
        if (treeMode.dataId.equals(treeModeC.dataId)) {
            List<TreeMode> treeModeList = treeMode.treeModeList;
            treeMode = treeModeC;
            treeMode.treeModeList = new ArrayList<>(treeModeList);
            return true;
        }

        //查找数据的上一节点是被查找数据，将查找数据添加进去
        if (treeMode.dataId.equals(treeModeC.pMuLu)) {
            if (treeMode.treeModeList == null) treeMode.treeModeList = new ArrayList<>();
            treeMode.treeModeList.add(treeModeC);
            return true;
        }

        if (treeMode.treeModeList == null) return false;
        for (TreeMode mode : treeMode.treeModeList) {
            if (mode.type != TreeMode.DATA_TYPE_MU_LU) continue;
            if (diGui(mode,treeModeC)) return true;
        }
        return false;
    }


    public List<TreeMode> getShowTreeModeList() {
        return showTreeModeList;
    }
    public List<TreeMode> getInPutTreeModeList() {
        return inPutTreeModeList;
    }
    public String getTitleName() {
        return titleName;
    }
    public int getShowLevel() {
        return showLevel;
    }
    public boolean isOnlyShowMuLu() {
        return isOnlyShowMuLu;
    }
    public int getIconMuLu() {
        return iconMuLu;
    }
    public int getIconData() {
        return iconData;
    }
    public int getSuoJinLevel() {
        return suoJinLevel;
    }
    public ISelectTreeListener getSelectTreeListener() {
        return selectTreeListener;
    }
    public List<TreeMode> getSearchTreeModeList() {
        return searchTreeModeList;
    }
    public Map<Integer, TreeMode> getSelectTreeModeMap() {
        return selectTreeModeMap;
    }
    @Override
    public void select(TreeMode treeMode) {
        selectTreeModeMap.put(treeMode.id,treeMode);
        if (selectTreeListener != null)selectTreeListener.select(treeMode);
    }

    @Override
    public void delete(TreeMode treeMode) {
        selectTreeModeMap.remove(treeMode.id);
        if (selectTreeListener != null)selectTreeListener.delete(treeMode);
    }
}
